#ifndef _DynamicVB__H_
#define _DynamicVB__H_

template <class VertexType>
VertexType* DynamicVB<VertexType>::LockVB(const uint32 theLockVertsCount, uint32 &nOffs, bool bWrite, bool bNonStalling)
{
  if (theLockVertsCount > m_nVerts)
  {
    assert(false);
		CryLogAlways("Locking vertex buffer. Requested size too large!");
    return NULL;
  }

  if (m_bLocked)
	{
		CryLogAlways("Locking vertex buffer when it is already locked!");
    return m_pLockedData;
	}

  uint32 theLockBytesCount = theLockVertsCount * m_nVertStride;
  HRESULT hr = S_OK;












  if (m_pVB)
  {
#if defined (DIRECT3D9)
    if (theLockVertsCount+m_nOffs > m_nVerts)
    {
      gcpRendD3D->m_RP.m_VertexStreams[3].pStream = NULL;
#if !defined(XENON) 
			m_pLockedData = NULL;
      hr = m_pVB->Lock(0, theLockBytesCount, (void **) &m_pLockedData, D3DLOCK_DISCARD);






































#endif
      nOffs = 0;
      m_nOffs = theLockVertsCount;
    }
    else
    {
#if !defined(XENON) && !defined(PS3)
			m_pLockedData = NULL;
      hr = m_pVB->Lock(m_nOffs*m_nVertStride, theLockBytesCount, (void **) &m_pLockedData, D3DLOCK_NOOVERWRITE);
			CHECK_HRESULT(hr);



















#endif
      nOffs = m_nOffs;
      m_nOffs += theLockVertsCount;
    }
#elif defined (DIRECT3D10)
		STALL_PROFILER("set vertex_buffer")
		D3D11_MAPPED_SUBRESOURCE mappedResource;
		memset(&mappedResource, 0x0, sizeof(mappedResource));
    if (theLockVertsCount+m_nOffs > m_nVerts)
    {
      D3D11_MAP Map = D3D11_MAP_WRITE_DISCARD;
      if (m_bReadWrite)
        Map = bWrite ? D3D11_MAP_WRITE : D3D11_MAP_READ;
      hr = gcpRendD3D->m_pd3dDeviceContext->Map(m_pVB, 0, Map, 0, &mappedResource);
			IF (FAILED(hr), 0) 
			{ 
				CHECK_HRESULT(hr);
				return NULL; 
			} 
			m_pLockedData = (VertexType*)mappedResource.pData;
      nOffs = 0;
      m_nOffs = theLockVertsCount;
    }
    else
    {
      byte *pD;
      D3D11_MAP Map = D3D11_MAP_WRITE_NO_OVERWRITE;
#if !defined(CAFE)
      if (m_bReadWrite && !bNonStalling)
        Map = bWrite ? D3D11_MAP_WRITE : D3D11_MAP_READ;
#endif
			hr = gcpRendD3D->m_pd3dDeviceContext->Map(m_pVB, 0, Map, 0, &mappedResource);
			IF (FAILED(hr), 0) 
			{ 
				CHECK_HRESULT(hr);
				return NULL; 
			} 
			pD = (byte*)mappedResource.pData;
      m_pLockedData = (VertexType *)(pD + m_nOffs*m_nVertStride);
      nOffs = m_nOffs;
      m_nOffs += theLockVertsCount;
    }



#endif
    assert(m_pLockedData != NULL);
    m_bLocked = true;
  }
	CHECK_HRESULT(hr);
  return m_pLockedData;
}





























template <class VertexType>
void DynamicVB<VertexType>::UnlockVB()
{
  if ((m_bLocked) && (m_pVB))
  {
		HRESULT hr = S_OK;
#if defined (DIRECT3D9)














		hr = m_pVB->Unlock();
		CHECK_HRESULT(hr);


#elif defined (DIRECT3D10)



		gcpRendD3D->GetDeviceContext()->Unmap(m_pVB, 0);
#endif
    assert(hr == S_OK);
    m_bLocked = false;
  }
}

template <class VertexType>
HRESULT DynamicVB<VertexType>::Bind(uint32 StreamNumber, int nBytesOffset, int nStride, uint32 nFreq)
{
  HRESULT h = gcpRendD3D->FX_SetVStream(StreamNumber, m_pVB, nBytesOffset, nStride==0 ? m_nVertStride : nStride, nFreq);
	CHECK_HRESULT(h);
  return h;
}

#endif  //_DynamicVB__H_
